package base;

public enum UnitType {
	/* format:
	 * UNIT_TYPE(unitTypeNumber, maxHP, maxMP, baseRange, baseSpeed, baseArmor, baseMaxDamage, baseMinDamage, unitHeight, costWood, costGold)
	 */
	//UNITS
	HUMAN_FOOTMAN (0, 60, 0, 1, 10, 2, 9, 2, 1, 0, 600),
	ORC_GRUNT (1, 60, 0, 1, 10, 2, 9, 2, 1, 0, 600),
	HUMAN_PEASANT (2, 30, 0, 1, 10, 0, 9, 2, 1, 0, 400),
	ORC_PEON (3, 30, 0, 1, 10, 0, 9, 2, 1, 0, 400),
	HUMAN_BALLISTA (4, 110, 0, 8, 5, 0, 80, 25, 1, 300, 900),
	ORC_CATAPULT (5, 110, 0, 8, 5, 0, 80, 25, 1, 300, 900),
	HUMAN_KNIGHT (6, 90, 0, 1, 13, 4, 12, 2, 1, 100, 800),
	ORC_OGRE (7, 90, 0, 1, 13, 4, 12, 2, 1, 100, 800),
	HUMAN_ARCHER (8, 40, 0, 4, 10, 0, 9, 3, 1, 50, 500),
	ORC_AXETHROWER (9, 40, 0, 4, 10, 0, 9, 3, 1, 50, 500),
	HUMAN_MAGE (10, 60, 255, 2, 8, 0, 9, 0, 1, 0, 1200),
	ORC_DEATH_KNIGHT (11, 60, 255, 2, 8, 0, 9, 0, 1, 0, 1200),
	HUMAN_PALADIN (12, 90, 255, 1, 13, 4, 12, 2, 1, 100, 800),
	ORC_OGRE_MAGE (13, 90, 255, 1, 13, 4, 12, 2, 1, 100, 800),
	HUMAN_DWARF_DEMO_SQUAD (14, 40, 0, 1, 11, 0, 1, 1, 1, 250, 750),
	ORC_GOBLIN_SAPPERS (15, 40, 0, 1, 11, 0, 1, 1, 1, 250, 750),
	HUMAN_RANGER (18, 50, 0, 4, 4, 0, 9, 3, 1, 50, 500),
	ORC_BESERKER (19, 50, 0, 4, 4, 0, 9, 3, 1, 50, 500),
	HUMAN_OIL_TANKER (26, 90, 0, 0, 10, 0, 0, 0, 1, 250, 400),
	ORC_OIL_TANKER (27, 90, 0, 0, 10, 0, 0, 0, 1, 250, 400),
	HUMAN_TRANSPORT (28, 150, 0, 0, 10, 0, 0, 0, 1, 200, 600),
	ORC_TRANSPORT (29, 150, 0, 0, 10, 0, 0, 0, 1, 200, 600),
	HUMAN_ELVEN_DESTROYER (30, 100, 0, 4, 10, 10, 35, 2, 1, 350, 700),
	ORC_TROLL_DESTROYER (31, 100, 0, 4, 10, 10, 35, 2, 1, 350, 700),
	HUMAN_BATTLESHIP (32, 150, 0, 6, 6, 15, 130, 50, 1, 500, 1000),
	ORC_OGRE_JUGGERNAUGHT (33, 150, 0, 6, 6, 15, 130, 50, 1, 500, 1000),
	HUMAN_GNOMISH_SUBMARINE (38, 60, 0, 4, 7, 0, 50, 10, 1, 150, 800),
	ORC_GIANT_TURTLE (39, 60, 0, 4, 7, 0, 50, 10, 1, 150, 800),
	HUMAN_GNOMISH_FLYING_MACHINE (40, 150, 0, 0, 17, 0, 0, 0, 1, 100, 500),
	ORC_GOBLIN_ZEPPELIN (41, 150, 0, 0, 17, 0, 0, 0, 1, 100, 500),
	HUMAN_GRYPHON_RIDER (42, 100, 0, 4, 14, 0, 16, 8, 1, 0, 2500),
	ORC_DRAGON (43, 100, 0, 4, 14, 0, 16, 8, 1, 0, 2500),
	EYE_OF_KILROGG (45, 100, 0, 0, 0, 0, 0, 0, 1, 0, 0),
	SKELETON (54, 50, 0, 1, 8, 0, 9, 2, 1, 0, 0),
	CRITTER (57, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0),
	//BUILDINGS
	HUMAN_FARM (58, 400, 0, 0, 0, 20, 0, 0, 2, 250, 500),
	ORC_PIG_FARM (59, 400, 0, 0, 0, 20, 0, 0, 2, 250, 500),
	HUMAN_BARRACKS (60, 800, 0, 0, 0, 20, 0, 0, 3, 450, 700),
	ORC_BARRACKS (61, 800, 0, 0, 0, 20, 0, 0, 3, 450, 700),
	HUMAN_CHURCH (62, 700, 0, 0, 0, 20, 0, 0, 3, 500, 900),
	ORC_ALTAR_OF_STORMS (63, 700, 0, 0, 0, 20, 0, 0, 3, 500, 900),
	HUMAN_WATCH_TOWER (64, 100, 0, 0, 0, 20, 0, 0, 2, 150, 550),
	ORC_WATCH_TOWER (65, 100, 0, 0, 0, 20, 0, 0, 2, 150, 550),
	HUMAN_STABLES (66, 500, 0, 0, 0, 20, 0, 0, 3, 300, 1000),
	ORC_OGRE_MOUND (67, 500, 0, 0, 0, 20, 0, 0, 3, 300, 1000),
	HUMAN_GNOMISH_INVENTOR (68, 500, 0, 0, 0, 20, 0, 0, 3, 400, 1000),
	ORC_GOBLIN_ALCHEMIST (69, 500, 0, 0, 0, 20, 0, 0, 3, 400, 1000),
	HUMAN_GRYPHON_AVIARY (70, 500, 0, 0, 0, 20, 0, 0, 3, 400, 1000),
	ORC_DRAGON_ROOST (71, 500, 0, 0, 0, 20, 0, 0, 3, 400, 1000),
	HUMAN_SHIPYARD (72, 1100, 0, 0, 0, 20, 0, 0, 3, 450, 800),
	ORC_SHIPYARD (73, 1100, 0, 0, 0, 20, 0, 0, 3, 450, 800),
	HUMAN_TOWN_HALL (74, 1200, 0, 0, 0, 20, 0, 0, 4, 800, 1200),
	ORC_GREAT_HALL (75, 1200, 0, 0, 0, 20, 0, 0, 4, 800, 1200),
	HUMAN_ELVEN_LUMBER_MILL (76, 600, 0, 0, 0, 20, 0, 0, 3, 450, 600),
	ORC_TROLL_LUMBER_MILL (77, 600, 0, 0, 0, 20, 0, 0, 3, 450, 600),
	HUMAN_FOUNDRY (78, 750, 0, 0, 0, 20, 0, 0, 3, 400, 700),
	ORC_FOUNDRY (79, 750, 0, 0, 0, 20, 0, 0, 3, 400, 700),
	HUMAN_MAGE_TOWER (80, 500, 0, 0, 0, 20, 0, 0, 3, 200, 1000),
	ORC_TEMPLE_OF_THE_DAMNED (81, 500, 0, 0, 0, 20, 0, 0, 3, 200, 1000),
	HUMAN_BLACKSMITH (82, 775, 0, 0, 0, 20, 0, 0, 3, 450, 800),
	ORC_BLACKSMITH (83, 775, 0, 0, 0, 20, 0, 0, 3, 450, 800),
	HUMAN_REFINERY (84, 600, 0, 0, 0, 20, 0, 0, 3, 350, 800),
	ORC_REFINERY (85, 600, 0, 0, 0, 20, 0, 0, 3, 350, 800),
	HUMAN_KEEP (88, 1400, 0, 0, 0, 20, 0, 0, 4, 1000, 2000),
	ORC_STRONGHOLD (89, 1400, 0, 0, 0, 20, 0, 0, 4, 1000, 2000),
	HUMAN_CASTLE (90, 1600, 0, 0, 0, 20, 0, 0, 4, 1200, 2500),
	ORC_FORTRESS (91, 1600, 0, 0, 0, 20, 0, 0, 4, 1200, 2500),
	HUMAN_GUARD_TOWER (96, 130, 0, 6, 0, 20, 16, 6, 2, 150, 550),
	ORC_GUARD_TOWER (97, 130, 0, 6, 0, 20, 16, 6, 2, 150, 550),
	HUMAN_CANNON_TOWER (98, 160, 0, 7, 0, 20, 50, 10, 2, 300, 1000),
	ORC_CANNON_TOWER (99, 160, 0, 7, 0, 20, 50, 10, 2, 300, 1000),
	HUMAN_WALL (103, 50, 0, 0, 0, 20, 0, 0, 1, 0, 0),
	ORC_WALL (104, 50, 0, 0, 0, 20, 0, 0, 1, 0, 0),
	//RESOURCES
	GOLDMINE (92, 99999999, 0, 0, 0, 0, 0, 0, 3, 0, 0), 
	OIL_PATCH (93, -1, 0, 0, 0, 0, 0, 0, 3, 0, 0),
	//MISC
	CORPSE (105, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
	
	
	private final int unitTypeNum;
	private final int maxHP;
	private final int maxMP;
	private final int baseRange;
	private final int baseSpeed;
	private final int baseArmor;
	private final int baseMaxDamage;
	private final int baseMinDamage;
	private final int unitHeight;
	private final int woodCost;
	private final int goldCost;
	
	
	UnitType(int unitTypeNum, int maxHP, int maxMP, 
			int baseRange, int baseSpeed, int baseArmor, 
			int baseMaxDamage, int baseMinDamage, int unitHeight,
			int woodCost, int goldCost) {
		this.unitTypeNum = unitTypeNum;
		this.maxHP = maxHP;
		this.maxMP = maxMP;
		this.baseRange = baseRange;
		this.baseSpeed = baseSpeed;
		this.baseArmor = baseArmor;
		this.baseMaxDamage = baseMaxDamage;
		this.baseMinDamage = baseMinDamage;
		this.unitHeight = unitHeight;
		this.woodCost = woodCost;
		this.goldCost = goldCost;
	}
	
	public int getMaxHP() {
		return this.maxHP;
	}
	
	public int getMaxMP() {
		return this.maxMP;
	}
	
	public int getMaxDamage(boolean[] advances) {
		int damage = this.baseMaxDamage;
		damage += calculateModifiers(advances);
		return damage;
	}

	private int calculateModifiers(boolean[] advances) {
		int damage = 0;
		switch (this) {
		case HUMAN_FOOTMAN:
		case ORC_PEON:
			if (advances[0] || advances[2]) {
				damage += 2;
			}
			if (advances[1] || advances[3]) {
				damage += 2;
			}
			break;
		case HUMAN_BALLISTA: //ballista
		case ORC_CATAPULT:
			if (advances[20] || advances[22]) {
				damage += 15;
			}
			if (advances[21] || advances[23]) {
				damage += 15;
			}
			break;
		case HUMAN_KNIGHT: //knight
		case ORC_OGRE:
			if (advances[0] || advances[2]) {
				damage += 2;
			}
			if (advances[1] || advances[3]) {
				damage += 2;
			}
			break;
		case HUMAN_ARCHER: //archer
		case ORC_AXETHROWER://axethrower
			if (advances[4] || advances[6]) {
				damage += 1;
			}
			if (advances[5] || advances[7]) {
				damage += 1;
			}
			break;
		case HUMAN_PALADIN: //paladin
		case ORC_OGRE_MAGE:
			if (advances[0] || advances[2]) {
				damage += 2;
			}
			if (advances[1] || advances[3]) {
				damage += 2;
			}
			break;
		case HUMAN_RANGER://ranger
			if (advances[27]) {
				damage += 1;
			}
		case ORC_BESERKER:
			if (advances[4] || advances[6]) {
				damage += 1;
			}
			if (advances[5] || advances[7]) {
				damage += 1;
			}
			break;
		case HUMAN_ELVEN_DESTROYER: //Destroyer
		case ORC_TROLL_DESTROYER:
			if (advances[12] || advances[14]) {
				damage += 5;
			}
			if (advances[13] || advances[15]) {
				damage += 5;
			}
			break;
		case HUMAN_BATTLESHIP: //Battleship
		case ORC_OGRE_JUGGERNAUGHT:
			if (advances[12] || advances[14]) {
				damage += 5;
			}
			if (advances[13] || advances[15]) {
				damage += 5;
			}
			break;
		}
		return damage;
	}

	public int getMinDamage(boolean[] advances) {
		int damage = this.baseMinDamage;
		damage += calculateModifiers(advances);
		return damage;
	}

	public int getRange(boolean[] advances) {
		int range = this.baseRange;
		switch (this) {
		case HUMAN_RANGER:
		case ORC_BESERKER: 
			if (advances == null || advances[25] || advances[29]) {
				range += 1;
			}
			break;
		}
		return range;
	}
	
	public int getSpeed() {
		return this.baseSpeed;
	}

	public int getArmor(boolean[] advances) {
		int armor = this.baseArmor;
		switch (this) {
		case HUMAN_FOOTMAN://footman
		case ORC_GRUNT: 
			if (advances[8] || advances[10]) {
				armor += 2;
			}
			if (advances[9] || advances[11]) {
				armor += 2;
			}
			break;
		case HUMAN_KNIGHT: //knight
		case ORC_OGRE:
			if (advances[8] || advances[10]) {
				armor += 2;
			}
			if (advances[9] || advances[11]) {
				armor += 2;
			}
			break;
		case HUMAN_PALADIN: //paladin
		case ORC_OGRE_MAGE:
			if (advances[8] || advances[10]) {
				armor += 2;
			}
			if (advances[9] || advances[11]) {
				armor += 2;
			}
			break;
		case HUMAN_TRANSPORT: //transport
		case ORC_TRANSPORT:
			if (advances[16] || advances[18]) {
				armor += 5;
			}
			if (advances[17] || advances[19]) {
				armor += 5;
			}
			break;
		case HUMAN_ELVEN_DESTROYER: //Destroyer
		case ORC_TROLL_DESTROYER:
			if (advances[16] || advances[18]) {
				armor += 5;
			}
			if (advances[17] || advances[19]) {
				armor += 5;
			}
			break;
		case HUMAN_BATTLESHIP: //Battleship
		case ORC_OGRE_JUGGERNAUGHT:
			if (advances[16] || advances[18]) {
				armor += 5;
			}
			if (advances[17] || advances[19]) {
				armor += 5;
			}
			break;
		}
		return armor;
	}

	public int getUnitHeight() {
		return this.unitHeight;
	}
	
	public int getUnitWidth() {
		return this.unitHeight;
	}
	
	public int getUnitTypeNum() {
		return this.unitTypeNum;
	}

	public static UnitType getUnitTypeEnumFromNum(int unitTypeNum) {
		switch (unitTypeNum) {
		case 0: return UnitType.HUMAN_FOOTMAN;
		case 1: return UnitType.ORC_GRUNT;
		case 2: return UnitType.HUMAN_PEASANT;
		case 3: return UnitType.ORC_PEON;
		case 4: return UnitType.HUMAN_BALLISTA;
		case 5: return UnitType.ORC_CATAPULT;
		case 6: return UnitType.HUMAN_KNIGHT;
		case 7: return UnitType.ORC_OGRE;
		case 8: return UnitType.HUMAN_ARCHER;
		case 9: return UnitType.ORC_AXETHROWER;
		case 10: return UnitType.HUMAN_MAGE;
		case 11: return UnitType.ORC_DEATH_KNIGHT;
		case 12: return UnitType.HUMAN_PALADIN;
		case 13: return UnitType.ORC_OGRE_MAGE;
		case 14: return UnitType.HUMAN_DWARF_DEMO_SQUAD;
		case 15: return UnitType.ORC_GOBLIN_SAPPERS;
		case 18: return UnitType.HUMAN_RANGER;
		case 19: return UnitType.ORC_BESERKER;
		case 26: return UnitType.HUMAN_OIL_TANKER;
		case 27: return UnitType.ORC_OIL_TANKER;
		case 28: return UnitType.HUMAN_TRANSPORT;
		case 29: return UnitType.ORC_TRANSPORT;
		case 30: return UnitType.HUMAN_ELVEN_DESTROYER;
		case 31: return UnitType.ORC_TROLL_DESTROYER;
		case 32: return UnitType.HUMAN_BATTLESHIP;
		case 33: return UnitType.ORC_OGRE_JUGGERNAUGHT;
		case 38: return UnitType.HUMAN_GNOMISH_SUBMARINE;
		case 39: return UnitType.ORC_GIANT_TURTLE;
		case 40: return UnitType.HUMAN_GNOMISH_FLYING_MACHINE;
		case 41: return UnitType.ORC_GOBLIN_ZEPPELIN;
		case 42: return UnitType.HUMAN_GRYPHON_RIDER;
		case 43: return UnitType.ORC_DRAGON;
		case 45: return UnitType.EYE_OF_KILROGG;
		case 54: return UnitType.SKELETON;
		case 57: return UnitType.CRITTER;
		case 58: return UnitType.HUMAN_FARM;
		case 59: return UnitType.ORC_PIG_FARM;
		case 60: return UnitType.HUMAN_BARRACKS;
		case 61: return UnitType.ORC_BARRACKS;
		case 62: return UnitType.HUMAN_CHURCH;
		case 63: return UnitType.ORC_ALTAR_OF_STORMS;
		case 64: return UnitType.HUMAN_WATCH_TOWER;
		case 65: return UnitType.ORC_WATCH_TOWER;
		case 66: return UnitType.HUMAN_STABLES;
		case 67: return UnitType.ORC_OGRE_MOUND;
		case 68: return UnitType.HUMAN_GNOMISH_INVENTOR;
		case 69: return UnitType.ORC_GOBLIN_ALCHEMIST;
		case 70: return UnitType.HUMAN_GRYPHON_AVIARY;
		case 71: return UnitType.ORC_DRAGON_ROOST;
		case 72: return UnitType.HUMAN_SHIPYARD;
		case 73: return UnitType.ORC_SHIPYARD;
		case 74: return UnitType.HUMAN_TOWN_HALL;
		case 75: return UnitType.ORC_GREAT_HALL;
		case 76: return UnitType.HUMAN_ELVEN_LUMBER_MILL;
		case 77: return UnitType.ORC_TROLL_LUMBER_MILL;
		case 78: return UnitType.HUMAN_FOUNDRY;
		case 79: return UnitType.ORC_FOUNDRY;
		case 80: return UnitType.HUMAN_MAGE_TOWER;
		case 81: return UnitType.ORC_TEMPLE_OF_THE_DAMNED;
		case 82: return UnitType.HUMAN_BLACKSMITH;
		case 83: return UnitType.ORC_BLACKSMITH;
		case 84: return UnitType.HUMAN_REFINERY;
		case 85: return UnitType.ORC_REFINERY;
		case 88: return UnitType.HUMAN_KEEP;
		case 89: return UnitType.ORC_STRONGHOLD;
		case 90: return UnitType.HUMAN_CASTLE;
		case 91: return UnitType.ORC_FORTRESS;
		case 92: return UnitType.GOLDMINE;
		case 96: return UnitType.HUMAN_GUARD_TOWER;
		case 97: return UnitType.ORC_GUARD_TOWER;
		case 98: return UnitType.HUMAN_CANNON_TOWER;
		case 99: return UnitType.ORC_CANNON_TOWER;
		case 103: return UnitType.HUMAN_WALL;
		case 104: return UnitType.ORC_WALL;
		case 105: return UnitType.CORPSE;
		default:
			//System.out.println("UnitType: enumFromID -- NOT GOOD :" + unitTypeNum);
			return CORPSE;
		}
	}

	/**
	 * @return the woodCost
	 */
	public int getWoodCost() {
		return woodCost;
	}

	/**
	 * @return the goldCost
	 */
	public int getGoldCost() {
		return goldCost;
	}
}

